home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-06-05 | 25.6 KB | 1,081 lines |
- /*
- File: Window.cp
-
- Contains: Implementation of TWindow, a base class which provides a
- framework for building way-cool windows which even John
- Sullivan would be happy with. Floating windows and “smart
- zooming” algorithms are based on code samples provided by
- Dean Yu. Tim Craycroft, the guy making the window manager
- do all this work for you has also been a great help.
-
- Written by: Dave Falkenburg
-
- Copyright: © 1993-1995 by Dave Falkenburg, all rights reserved.
-
- Change History (most recent first):
-
- <14> 1/24/95 DRF DoMenuSelection now returns a Boolean. Added some default
- behavior for handling the close menu item-- this will change
- when we make some things recordable.
- <13> 1/20/95 DRF Fix the “calling DisposeWindow on DialogPtr” problem reported by
- Gary Powell @ Adobe by adding a cheezy flag that TWindow
- initializes, but TDialogWindow slams. In TWindow::Close, we
- check this flag and call DisposeDialog instead of DisposeWindow,
- surely preventing memory leaks for complex dialogs.
- <12> 1/3/95 DRF Add Nitin’s changes for Drag handling: a ClickAndDrag method.
- <11> 1/3/95 DRF DoMenuCommand now returns a Boolean. Also got rid of
- conditionals for ClipAbove: by the time this gets to print
- everyone should be using Universal Headers 2.0.
- <10> 12/6/94 DRF Rolled in David Den Boer’s fixes. Also add the conditionals for
- newest universal headers again.
- <9> 11/23/94 DRF Bite the bullet just require the latest universal headers
- <8> 11/17/94 DRF Add casts for CFront & PPCC. Also dealt with the change to
- ClipAbove in the latest universal headers.
- <7> 11/12/94 DRF Added AdjustMenusBeforeMenuSelection.
- <6> 11/8/94 DRF Add some better menu handling methods.
- <5> 9/27/94 DRF AppLib.h is now Sprocket.h
- <4> 9/9/94 DRF Reorganized headers and removed redundant #includes.
- <3> 9/4/94 DRF Added DrawJustTheGrowIcon.
- <2> 8/27/94 DRF In TWindow::Close, call window’s (de)Activate method before
- closing so that menus can be properly updated.
-
- To Do: Make sure invisible windows can be created & managed
- Handle modal windows as another class of windows
- Fix activate bugs when showing and hiding windows
- Window positioning methods (getters and setters)
- Display Manager support
- Changes to support AEObject model
- */
-
- #include "Sprocket.h"
- #include "Window.h"
- #include "UtilityClasses.h"
-
- #include <Script.h> // for GetMBarHeight()
- #include <LowMem.h> // for LMGetWindowList()
-
-
- UInt32 TWindow::fgModalState = 0;
-
-
- const WindowRef kNoFloatingWindows = (WindowRef) -1;
- const WindowRef kNoModalWindows = (WindowRef) -1;
-
- const short kScreenEdgeSlop = 4;
- const short kSpaceForFinderIcons = 64;
- const short kMinimumTitleBarHeight = 21;
- const short kMinimumWindowSize = 32;
-
-
- static void HiliteShowHideFloatingWindows(Boolean hiliting,Boolean hiding);
-
- static pascal void CalculateWindowAreaOnDevice(short depth,short deviceFlags,GDHandle targetDevice,long userData);
-
- struct CalcWindowAreaDeviceLoopUserData
- {
- GDHandle fScreenWithLargestPartOfWindow;
- long fLargestArea;
- Rect fWindowBounds;
- };
-
-
-
- TWindow::TWindow()
- {
- fIsDialogWindow = false;
- }
-
-
- TWindow::~TWindow()
- {
- WindowRef newFrontWindow = NULL;
-
- if (fWindow)
- {
- if (FrontNormalWindow() == fWindow)
- newFrontWindow = GetNextWindow(fWindow);
-
- this->Activate(false);
-
- if (fIsDialogWindow)
- DisposeDialog((DialogRef) fWindow);
- else
- DisposeWindow(fWindow);
-
- if (fWindowType == kModalWindow)
- this->ExitModalState();
-
- if (newFrontWindow)
- HiliteAndActivateWindow(newFrontWindow,true);
- }
- }
-
-
-
- void
- TWindow::CreateWindow(WindowType typeOfWindowToCreate /* = kNormalWindow */)
- {
- WindowRef behindWindow;
- WindowRef oldTopWindow = NULL;
-
- if (typeOfWindowToCreate == kNormalWindow)
- {
- // normal windows are always created behind modal and floaters
-
- behindWindow = LastFloatingWindow();
- oldTopWindow = FrontNormalWindow();
- }
- else if (typeOfWindowToCreate == kFloatingWindow)
- {
- // always create floaters behind modal windows
-
- behindWindow = LastModalWindow();
- oldTopWindow = FrontFloatingWindow();
- }
- else if (typeOfWindowToCreate == kModalWindow)
- {
- // modal windows are always created frontmost
-
- behindWindow = (WindowRef) -1;
- oldTopWindow = FrontModalWindow();
-
- this->EnterModalState();
- }
-
-
- fWindow = this->MakeNewWindow(behindWindow);
-
-
- if (fWindow != NULL)
- {
- SetWRefCon(fWindow,(long) this);
- fIsVisible = IsWindowVisible ( fWindow );
- fWindowType = typeOfWindowToCreate;
- SetWindowKind(fWindow,typeOfWindowToCreate);
-
- if ((fIsVisible) && (fgModalState == 0))
- {
- if (fWindowType == kNormalWindow)
- HiliteAndActivateWindow(oldTopWindow,false);
-
- else if (fWindowType == kFloatingWindow)
- HiliteAndActivateWindow(oldTopWindow,true);
-
- HiliteAndActivateWindow(fWindow,true);
- }
- }
- else
- {
- if (fWindowType == kModalWindow)
- this->ExitModalState();
- }
- }
-
-
- void
- TWindow::AdjustCursor(EventRecord * /* anEvent */)
- {
- }
-
-
- void
- TWindow::Idle(EventRecord * /* anEvent */)
- {
- }
-
- void
- TWindow::Activate(Boolean /* activating */)
- {
- }
-
- void
- TWindow::Draw(void)
- {
- }
-
- void
- TWindow::Click(EventRecord * /* anEvent */)
- {
- }
-
- void
- TWindow::KeyDown(EventRecord * /* anEvent */)
- {
- }
-
-
- void
- TWindow::Select(void)
- {
- WindowRef oldTopWindow, behindWindow;
-
- if (fWindowType == kNormalWindow)
- {
- oldTopWindow = FrontNormalWindow();
- behindWindow = LastFloatingWindow();
- if (behindWindow == kNoFloatingWindows)
- behindWindow = LastModalWindow();
- }
- else if (fWindowType == kFloatingWindow)
- {
- oldTopWindow = FrontFloatingWindow();
- behindWindow = LastModalWindow();
- }
- else if (fWindowType == kModalWindow)
- {
- oldTopWindow = FrontModalWindow();
- behindWindow = (WindowRef) -1;
- }
-
- if (fWindow != oldTopWindow)
- {
- if (behindWindow == (WindowRef) -1)
- SelectWindow(fWindow);
- else
- SendBehind(fWindow,behindWindow);
-
- if (oldTopWindow != NULL)
- {
- if (fWindowType == kFloatingWindow)
- HiliteWindow(oldTopWindow,true);
- else
- HiliteAndActivateWindow(oldTopWindow,false);
- }
-
- HiliteAndActivateWindow(fWindow,true);
- }
- }
-
-
- void
- TWindow::Drag(Point startPoint)
- {
- GrafPtr savePort;
- KeyMap theKeyMap;
- Boolean commandKeyDown = false;
- long dragResult;
-
- if (WaitMouseUp()) // de-bounce?
- {
- // Set up the Window Manager port.
-
- GetPort(&savePort);
- SetPort(gWindowManagerPort);
- SetClip(GetGrayRgn());
-
- // Check to see if the command key is down.
-
- GetKeys(theKeyMap);
- commandKeyDown = ((theKeyMap[1] & 0x8000) != 0);
-
- if (commandKeyDown)
- {
- // We’re not going to change window ordering,
- // so make sure that we don’t drag in front of
- // other windows which may be in front of ours.
-
- ClipAbove(fWindow);
- }
- else if (fWindowType != kFloatingWindow)
- {
- // We’re dragging a normal window, so make sure
- // that we don’t drag in front of any floating
- // windows.
-
- ClipAbove(FrontNormalWindow());
- }
-
- // Drag an outline of the window around the desktop.
- // NOTE: DragGrayRgn destroys the region passed in, so make a copy
-
- RgnHandle tempRgn = NewRgn();
-
- GetWindowStructureRgn(fWindow, tempRgn);
- dragResult = DragGrayRgn(tempRgn, startPoint, &gDeskRectangle, &gDeskRectangle, noConstraint, nil);
-
- DisposeRgn(tempRgn);
-
- SetPort(savePort); // Get back to old port
-
- if ((dragResult != 0) && (dragResult != 0x80008000))
- this->Nudge((short) (dragResult & 0xFFFF),(short) (dragResult >> 16));
- }
-
- if (!commandKeyDown)
- this->Select();
- }
-
-
- void
- TWindow::Nudge(short horizontalDistance, short verticalDistance)
- {
- short newHorizontalPosition, newVerticalPosition;
- RgnHandle tempRgn = NewRgn ();
-
- GetWindowContentRgn ( fWindow, tempRgn );
- newHorizontalPosition = (short) (**tempRgn).rgnBBox.left + horizontalDistance;
- newVerticalPosition = (short) (**tempRgn).rgnBBox.top + verticalDistance;
- DisposeRgn ( tempRgn );
-
- MoveWindow(fWindow,newHorizontalPosition,newVerticalPosition,false);
- }
-
-
- void
- TWindow::Grow(Point startPoint)
- {
- GrafPtr oldPort;
- long newSize;
- Rect oldWindowRect,resizeLimits;
-
- GetPort(&oldPort);
-
- GetWindowSizeLimits(&resizeLimits);
- newSize = GrowWindow(fWindow,startPoint,&resizeLimits);
- if (newSize)
- {
- oldWindowRect = GetWindowPort ( fWindow )->portRect;
- SizeWindow ( fWindow, (short) newSize, (short) (newSize >> 16), true );
- SetPortWindowPort ( fWindow );
- resizeLimits = GetWindowPort ( fWindow )->portRect;
- this->AdjustForNewWindowSize(&oldWindowRect,&resizeLimits);
- }
-
- SetPort(oldPort);
- }
-
-
- void
- TWindow::Zoom(short zoomState)
- {
- GrafPtr oldPort;
- FontInfo systemFontInfo;
- short titleBarHeight;
- Rect bestScreenRect,perfectWindowRect,scratchRect;
- short amountOffscreen;
- // WindowPeek windowAsWindowPeek = (WindowPeek) fWindow;
- GDHandle bestDevice;
-
- GetPort(&oldPort);
-
- // Figure out the height of the title bar so we can properly position
- // a window. The algorithm is stolen from the System 7.x 'WDEF' (0)
- //
- // This probably isn’t the best thing to do: A better way might be
- // to diff the structure and content region rectangles?
-
- SetPort(gWindowManagerPort);
- GetFontInfo(&systemFontInfo);
- titleBarHeight = (short) (systemFontInfo.ascent + systemFontInfo.descent + 4);
- if ((titleBarHeight % 2) == 1)
- titleBarHeight--;
- if (titleBarHeight < kMinimumTitleBarHeight)
- titleBarHeight = kMinimumTitleBarHeight;
-
-
- // Only do the voodoo magic if we are really “zooming” the window.
-
- if (zoomState == inZoomOut)
- {
- FindScreenRectWithLargestPartOfWindow(fWindow,&bestScreenRect,&bestDevice);
- bestScreenRect.top += titleBarHeight;
-
- this->GetPerfectWindowSize(&perfectWindowRect);
- OffsetRect(&perfectWindowRect,-perfectWindowRect.left,-perfectWindowRect.top);
-
- // Take the zero-pined perfect window size and move it to
- // the top left of the window’s content region.
-
- RgnHandle tempRgn = NewRgn ();
- GetWindowContentRgn ( fWindow, tempRgn );
- OffsetRect ( &perfectWindowRect,
- (**tempRgn).rgnBBox.left, (**tempRgn).rgnBBox.top );
- DisposeRgn ( tempRgn );
-
-
- // Does perfectWindowRect fit completely on the best screen?
-
- SectRect(&perfectWindowRect, &bestScreenRect, &scratchRect);
- if (!EqualRect(&perfectWindowRect, &scratchRect))
- {
- // SectRect sez perfectWindowRect doesn’t completely fit
- // on the screen, so bump the window so that more of it fits.
-
- // Make sure that the left edge of perfectWindowRect is forced
- // onto the best screen. This is in case we are bumping
- // the window to the right.
-
- amountOffscreen = bestScreenRect.left - perfectWindowRect.left;
- if (amountOffscreen > 0)
- {
- perfectWindowRect.left += amountOffscreen;
- perfectWindowRect.right += amountOffscreen;
- }
-
- // Make sure that the left edge of perfectWindowRect is forced
- // onto the best screen. This is in case we are bumping
- // the window downward to a new screen.
-
- amountOffscreen = bestScreenRect.top - perfectWindowRect.top;
- if (amountOffscreen > 0)
- {
- perfectWindowRect.top += amountOffscreen;
- perfectWindowRect.bottom += amountOffscreen;
- }
-
- // If right edge of window falls off the screen,
- // Move window to the left until the right edge IS on the screen
- // OR the left edge is at bestScreenRect.left
-
- amountOffscreen = perfectWindowRect.right - bestScreenRect.right;
- if (amountOffscreen > 0)
- {
- // Are we going to push the left edge offscreen? If so, change the
- // offset so we move the window all the way over to the left.
-
- if ((perfectWindowRect.left - amountOffscreen) < bestScreenRect.left)
- amountOffscreen = perfectWindowRect.left - bestScreenRect.left;
-
- perfectWindowRect.left -= amountOffscreen;
- perfectWindowRect.right -= amountOffscreen;
- }
-
- // If bottom edge of window falls off the screen,
- // Move window to up until the bottom edge IS on the screen
- // OR the top edge is at bestScreenRect.top
-
- amountOffscreen = perfectWindowRect.bottom - bestScreenRect.bottom;
- if (amountOffscreen > 0)
- {
- // Are we going to push the top edge offscreen? If so, change the
- // offset so we move the window just to the top.
-
- if ((perfectWindowRect.top - amountOffscreen) < bestScreenRect.top)
- amountOffscreen = perfectWindowRect.top - bestScreenRect.top;
-
- perfectWindowRect.top -= amountOffscreen;
- perfectWindowRect.bottom -= amountOffscreen;
- }
-
- SectRect(&perfectWindowRect, &bestScreenRect, &scratchRect);
- if (!EqualRect(&perfectWindowRect, &scratchRect))
- {
- // The edges of the window still fall offscreen,
- // so make the window smaller until it fits.
-
- if (perfectWindowRect.bottom > bestScreenRect.bottom)
- perfectWindowRect.bottom = bestScreenRect.bottom;
-
- // If the right edge is still falling off,
- // save space for Finder’s disk icons as well.
-
- if (perfectWindowRect.right > bestScreenRect.right)
- {
- perfectWindowRect.right = bestScreenRect.right;
-
- // If we were on the main screen, leave room for Finder icons, too.
-
- if (bestDevice == GetMainDevice())
- perfectWindowRect.right -= kSpaceForFinderIcons;
- }
- }
- }
-
- // Stash our new rectangle inside of the Window’s dataHandle
- // so that ZoomWindow does the right thing.
-
- // (**((WStateDataHandle) (windowAsWindowPeek->dataHandle))).stdState = perfectWindowRect;
- SetWindowStandardState ( fWindow, &perfectWindowRect );
- }
-
- // HEY YOU! Don’t forget to set the port to the window being zoomed
- // Why, you ask? Because IM-IV-50 says to; otherwise you die
-
- SetPortWindowPort ( fWindow );
-
- Rect oldWindowRect = GetWindowPort ( fWindow )->portRect;
- ZoomWindow(fWindow,zoomState,false);
- Rect newWindowRect = GetWindowPort ( fWindow )->portRect;
- this->AdjustForNewWindowSize(&oldWindowRect,&newWindowRect);
-
- SetPort(oldPort);
- }
-
- void
- TWindow::ShowHide(Boolean showFlag)
- {
- // Here we need the “::” in front of ShowHide to indicate we are calling
- // the global function, and not the method ShowHide. Unintended recursion
- // can do bad things to the unsuspecting programmer.
-
- // Some C++ programmers would always prepend the “::” on function calls.
-
- ::ShowHide(fWindow,showFlag);
- fIsVisible = showFlag;
- }
-
-
- Boolean
- TWindow::EventFilter(EventRecord * /* theEvent */)
- {
- return false;
- }
-
-
- void
- TWindow::GetPerfectWindowSize(Rect *perfectSize)
- {
- *perfectSize = qd.screenBits.bounds;
- }
-
-
- void
- TWindow::GetWindowSizeLimits(Rect *limits)
- {
- limits->top = limits->left = kMinimumWindowSize;
- limits->right = gDeskRectangle.right - gDeskRectangle.left;
- limits->bottom = gDeskRectangle.bottom - gDeskRectangle.top;
- }
-
-
- void
- TWindow::AdjustForNewWindowSize(Rect * /* oldRect */, Rect * /* newSize */)
- {
- }
-
-
- Boolean
- TWindow::IsVisible(void)
- {
- return fIsVisible;
- }
-
-
- Boolean
- TWindow::CanClose(void)
- {
- return true;
- }
-
-
- Boolean
- TWindow::Close(void)
- {
- delete this;
- return true;
- }
-
-
- void
- TWindow::AdjustMenusBeforeMenuSelection(void)
- {
- }
-
-
- void
- TWindow::AdjustMenusAfterMenuSelection(void)
- {
- }
-
-
- Boolean
- TWindow::DoMenuSelection(short /* menu */, short /* item */)
- {
- return false;
- }
-
-
- Boolean
- TWindow::DoMenuCommand(unsigned long menuCommand)
- {
- if (menuCommand == cClose)
- {
- if (this->CanClose())
- return this->Close();
- }
-
- return false;
- }
-
-
- ///////////////////////////////////////////////////////////////////////////
- //
- // Drag Manager callback routines which dispatch to a window’s method
- //
-
- /* static */ pascal OSErr
- TWindow::CallDragTrackingHandler(DragTrackingMessage dragMessage,WindowRef theWindow,void * /* refCon */,DragReference theDrag)
- {
- TWindow *wobj = GetWindowObject(theWindow);
-
- if (wobj)
- return(wobj->HandleDrag(dragMessage,theDrag));
- else
- return dragNotAcceptedErr;
- }
-
-
- /* static */ pascal OSErr
- TWindow::CallDragReceiveHandler(WindowRef theWindow,void * /* refCon */,DragReference theDrag)
- {
- TWindow *wobj = GetWindowObject(theWindow);
-
- if (wobj)
- return(wobj->HandleDrop(theDrag));
- else
- return dragNotAcceptedErr;
- }
-
-
- OSErr
- TWindow::HandleDrag(DragTrackingMessage dragMessage,DragReference theDrag)
- {
- OSErr result = dragNotAcceptedErr;
-
- switch (dragMessage)
- {
- case dragTrackingEnterWindow:
- result = this->DragEnterWindow(theDrag);
- break;
-
- case dragTrackingInWindow:
- result = this->DragInWindow(theDrag);
- break;
-
- case dragTrackingLeaveWindow:
- result = this->DragLeaveWindow(theDrag);
- break;
-
- default:
- break;
- }
-
- return result;
- }
-
-
- OSErr
- TWindow::HandleDrop(DragReference /* theDrag */)
- {
- return dragNotAcceptedErr;
- }
-
-
- OSErr
- TWindow::DragEnterWindow(DragReference /* theDrag */)
- {
- return dragNotAcceptedErr;
- }
-
-
- OSErr
- TWindow::DragInWindow(DragReference /* theDrag */)
- {
- return dragNotAcceptedErr;
- }
-
-
- OSErr
- TWindow::DragLeaveWindow(DragReference /* theDrag */)
- {
- return dragNotAcceptedErr;
- }
-
-
- Boolean
- TWindow::IsPointInContentRgn( Point pt )
- {
- RgnHandle tempRgn = NewRgn();
-
- GetWindowContentRgn(fWindow, tempRgn);
- Boolean result = PtInRgn( pt, tempRgn );
-
- DisposeRgn(tempRgn);
-
- return result;
- }
-
-
- Boolean
- TWindow::IsDragInContentRgn( DragReference dragRef )
- {
- Point globalMouse;
- OSErr err;
-
- err = GetDragMouse( dragRef, &globalMouse, 0L );
-
- if ( err == noErr )
- return( this->IsPointInContentRgn( globalMouse ) );
- else
- return( false );
- }
-
-
- Rect
- TWindow::GetContentsBounds(void)
- {
- RgnHandle tempRgn = NewRgn();
- Rect r;
-
- GetWindowContentRgn(fWindow, tempRgn);
- r = (**tempRgn).rgnBBox;
-
- DisposeRgn(tempRgn);
- return r;
- }
-
-
- DeviceLoopDrawingUPP CallCalcWindowAreaOnDevice = NewDeviceLoopDrawingProc(&CalculateWindowAreaOnDevice);
-
- void
- TWindow::FindScreenRectWithLargestPartOfWindow(WindowRef aWindow,Rect *theBestScreenRect,GDHandle * theBestDevice)
- {
- RgnHandle copyOfWindowStrucRgn;
- CalcWindowAreaDeviceLoopUserData deviceLoopData;
-
- // Use DeviceLoop to find out what GDevice contains the largest
- // portion of the supplied window.
- //
- // NOTE: Assumes thePort == the Window Manager Port because we using
- // the window strucRgn, not contRgn.
-
- deviceLoopData.fScreenWithLargestPartOfWindow = nil;
- deviceLoopData.fLargestArea = -1;
-
- RgnHandle tempRgn = NewRgn ();
- GetWindowContentRgn ( aWindow, tempRgn );
- deviceLoopData.fWindowBounds = (**tempRgn).rgnBBox;
- DisposeRgn ( tempRgn );
-
- copyOfWindowStrucRgn = NewRgn();
- GetWindowStructureRgn ( aWindow, copyOfWindowStrucRgn );
-
- DeviceLoop(copyOfWindowStrucRgn,CallCalcWindowAreaOnDevice,(long) &deviceLoopData,singleDevices);
-
- DisposeRgn(copyOfWindowStrucRgn);
-
- *theBestDevice = deviceLoopData.fScreenWithLargestPartOfWindow;
- *theBestScreenRect = (**(deviceLoopData.fScreenWithLargestPartOfWindow)).gdRect;
-
- // Leave some space around the edges of the screen so window look good, AND
- // if the best device is the main screen, leave space for the Menubar
-
- InsetRect(theBestScreenRect,kScreenEdgeSlop,kScreenEdgeSlop);
- if (GetMainDevice() == deviceLoopData.fScreenWithLargestPartOfWindow)
- theBestScreenRect->top += GetMBarHeight();
- }
-
-
-
- ////////////////////////////////////////////////////////////////////////
- //
- // Utility functions
- //
-
- TWindow *
- GetWindowObject(WindowRef aWindow)
- {
- short wKind;
-
- if (aWindow != nil)
- {
- wKind = GetWindowKind ( aWindow );
-
- if (wKind >= userKind)
- {
- // All windowKinds >= userKind are based upon TWindow
-
- return (TWindow *) GetWRefCon(aWindow);
- }
- }
- return (TWindow *) nil;
- }
-
-
-
-
- /* static */ WindowRef
- TWindow::GetNewWindow(short windowID, void *wStorage, WindowRef behind)
- {
- if (gHasColorQuickdraw)
- return GetNewCWindow(windowID,wStorage,behind);
- else
- return GetNewWindow(windowID,wStorage,behind);
- }
-
-
- /* static */ WindowRef
- TWindow::NewWindow(void *wStorage, const Rect *boundsRect, ConstStr255Param title, Boolean visible, short theProc, WindowRef behind, Boolean goAwayFlag, long refCon)
- {
- if (gHasColorQuickdraw)
- return NewCWindow(wStorage,boundsRect,title,visible,theProc,behind,goAwayFlag,refCon);
- else
- return NewWindow(wStorage,boundsRect,title,visible,theProc,behind,goAwayFlag,refCon);
- }
-
-
- /* static */ void
- TWindow::DrawGrowIcon(WindowRef aWindow)
- {
- TGraphicsContext graphicsContext((GrafPtr) aWindow);
- Rect growBoxRect;
-
- // clip to just the bottom right corner of the window
-
- growBoxRect = GetWindowPort(aWindow)->portRect;
- growBoxRect.top = growBoxRect.bottom - kScrollbarWidth + 1;
- growBoxRect.left= growBoxRect.right - kScrollbarWidth + 1;
- ClipRect(&growBoxRect);
-
- ::DrawGrowIcon(aWindow);
- }
-
-
- ///////////////////////////////////////////////////////////////////////////
- //
- // WindowList functions
- //
-
-
- /* static */ WindowRef
- TWindow::FrontNonFloatingWindow()
- {
- WindowRef aWindow = LMGetWindowList();
-
- // Loop through window list until we find a modal or normal window,
- // while skipping over invisible and/or floating windows
-
- while (aWindow != NULL)
- {
- if (IsWindowVisible(aWindow))
- {
- if (GetWindowKind(aWindow) != kFloatingWindow)
- break;
- }
-
- aWindow = GetNextWindow(aWindow);
- }
-
- return aWindow;
- }
-
-
- /* static */ WindowRef
- TWindow::FrontModalWindow()
- {
- WindowRef aWindow = LMGetWindowList();
-
- // Loop through visible windows until we find a visible modal window
- // or we get to another kind of window
-
- while ((aWindow != NULL) && (GetWindowKind(aWindow) == kModalWindow))
- {
- if (IsWindowVisible(aWindow))
- return aWindow;
-
- aWindow = GetNextWindow ( aWindow );
- }
-
- return NULL;
- }
-
-
- /* static */ WindowRef
- TWindow::LastModalWindow()
- {
- WindowRef aWindow = LMGetWindowList();
- WindowRef lastModal = (WindowRef) kNoModalWindows;
- SInt16 wKind;
-
- while ((aWindow != NULL) && ((wKind = GetWindowKind(aWindow)) == kModalWindow))
- {
- if (IsWindowVisible(aWindow) && (wKind == kModalWindow))
- lastModal = aWindow;
-
- aWindow = GetNextWindow(aWindow);
- }
-
- return lastModal;
- }
-
-
- /* static */ WindowRef
- TWindow::FrontFloatingWindow()
- {
- WindowRef aWindow = LMGetWindowList();
- SInt16 wKind;
-
- // Loop through visible windows until we find a visible floating window
- // or we get to another kind of window
-
- while ((aWindow != NULL) && ((wKind = GetWindowKind(aWindow)) <= kFloatingWindow))
- {
- if (IsWindowVisible(aWindow) && (wKind == kFloatingWindow))
- return aWindow;
-
- aWindow = GetNextWindow ( aWindow );
- }
-
- return NULL;
- }
-
-
- /* static */ WindowRef
- TWindow::LastFloatingWindow()
- {
- WindowRef aWindow = LMGetWindowList();
- WindowRef lastFloater = (WindowRef) kNoFloatingWindows;
- SInt16 wKind;
-
- while ((aWindow != NULL) && ((wKind = GetWindowKind(aWindow)) <= kFloatingWindow))
- {
- if (IsWindowVisible(aWindow) && (wKind == kFloatingWindow))
- lastFloater = aWindow;
-
- aWindow = GetNextWindow(aWindow);
- }
-
- return lastFloater;
- }
-
-
- /* static */ WindowRef
- TWindow::FrontNormalWindow()
- {
- WindowRef aWindow = LMGetWindowList();
- SInt16 wKind;
-
- // Loop through visible windows until we find a visible floating window
- // or we get to another kind of window
-
- while ((aWindow != NULL) && ((wKind = GetWindowKind(aWindow)) <= kNormalWindow))
- {
- if (IsWindowVisible(aWindow) && (wKind == kNormalWindow))
- return aWindow;
-
- aWindow = GetNextWindow ( aWindow );
- }
-
- return NULL;
- }
-
-
-
- /* static */ void
- TWindow::HiliteAndActivateWindow(WindowRef aWindow,Boolean active)
- {
- GrafPtr oldPort;
- TWindow * wobj = GetWindowObject(aWindow);
-
- if (aWindow)
- {
- ::HiliteWindow(aWindow,active);
-
- if (wobj != nil)
- {
- GetPort(&oldPort);
- SetPortWindowPort ( aWindow );
- wobj->Activate(active);
- SetPort(oldPort);
- }
- }
- }
-
-
- /* static */ void
- TWindow::SuspendResumeWindows(Boolean resuming)
- {
- // When we suspend/resume, hide/show all the visible floaters
-
- HiliteShowHideFloatingWindows(resuming,true);
- }
-
-
- /* static */ void
- TWindow::EnterModalState()
- {
- // When we display a modal dialog, we need to unhighlight
- // all visible floaters. We also need to re-hilite them
- // afterwards.
-
- if (fgModalState++ == 0)
- HiliteShowHideFloatingWindows(false,false);
-
- TMenuBar::EnterModalState();
- }
-
-
- /* static */ void
- TWindow::ExitModalState()
- {
- // When we display a modal dialog, we need to unhighlight
- // all visible floaters. We also need to re-hilite them
- // afterwards.
-
- if (--fgModalState == 0)
- HiliteShowHideFloatingWindows(true,false);
-
- TMenuBar::ExitModalState();
- }
-
-
- void
- HiliteShowHideFloatingWindows(Boolean hiliting,Boolean dohiding)
- {
- WindowRef aWindow;
- TWindow * wobj;
-
- TWindow::HiliteAndActivateWindow(TWindow::FrontNonFloatingWindow(),hiliting);
-
- aWindow = LMGetWindowList();
- while ( aWindow != nil && GetWindowKind ( aWindow ) == TWindow::kFloatingWindow )
- {
- wobj = GetWindowObject ( aWindow );
-
- // If we are hiding or showing, only hide/show windows
- // that were visible to begin with.
-
- // NOTE: We use our copy of the visible flag so we can
- // automatically show floaters on a resume event.
-
- // NOTE: Since this isn’t a method of TWindow, we don’t
- // really need the “::” on ShowHide, but as long
- // as we’re trying to avoid ambiguity.
-
- if (dohiding && (wobj != nil) && (wobj->IsVisible()))
- ::ShowHide(aWindow,hiliting);
-
- // All floaters are hilited if any floater is hilited
-
- HiliteWindow( aWindow,hiliting);
- aWindow = GetNextWindow ( aWindow );
- }
- }
-
-
- ///////////////////////////////////////////////////////////////////////////
- //
- // Routines used for dealing with windows and multiple screens
- //
-
- pascal void
- CalculateWindowAreaOnDevice(short /* depth */,short /* deviceFlags */,GDHandle targetDevice,long userData)
- {
- CalcWindowAreaDeviceLoopUserData * deviceLoopDataPtr;
- long windowAreaOnThisScreen;
- Rect windowRectOnThisScreen;
-
- deviceLoopDataPtr = (CalcWindowAreaDeviceLoopUserData *) userData;
-
- SectRect(&deviceLoopDataPtr->fWindowBounds, &(**targetDevice).gdRect,&windowRectOnThisScreen);
- OffsetRect(&windowRectOnThisScreen,-windowRectOnThisScreen.left,-windowRectOnThisScreen.top);
- windowAreaOnThisScreen = windowRectOnThisScreen.right * windowRectOnThisScreen.bottom;
-
- if (windowAreaOnThisScreen > deviceLoopDataPtr->fLargestArea)
- {
- deviceLoopDataPtr->fLargestArea = windowAreaOnThisScreen;
- deviceLoopDataPtr->fScreenWithLargestPartOfWindow = targetDevice;
- }
- }
-
-